10670
11042
Obecnie piszę podstawowy parser dla smaku XML. W ramach ćwiczenia implementuję parser oparty na tabeli LL.
Oto mój przykład gramatyki BNF:
% ciąg danych nazwy tokena
%% / * LL (1) * /
doc: elem
elem: "<" open_tag
open_tag: nazwa attr close_tag
close_tag: ">" elem_or_data ""
| „/>”
;
elem_or_data: "<" open_tag elem_or_data
| data elem_or_data
| / * epsilon * /
;
atr: nazwa ":" ciąg znaków atr
| / * epsilon * /
;
Czy ta gramatyka jest poprawna?
Każdy literał terminala znajduje się w cudzysłowie. Abstrakcyjne terminale są określane przez% token.
Koduję odręczny lekser, aby przekształcić moje dane wejściowe w listę tokenów. Jak tokenizować abstrakcyjne terminale? 
Klasycznym podejściem byłoby napisanie wyrażenia regularnego (lub innego mechanizmu rozpoznającego) dla każdego możliwego terminala.
To, co nazywacie „abstrakcyjnymi” terminalami, które są doskonale konkretne, są w rzeczywistości terminalami, których skojarzone wzorce rozpoznają więcej niż jeden możliwy ciąg wejściowy. Faktycznie rozpoznany ciąg (lub jakaś obliczona funkcja tego ciągu) powinien zostać przekazany do parsera jako wartość semantyczna tokena.
Nominalnie w każdym punkcie ciągu wejściowego tokeniser uruchomi wszystkie urządzenia rozpoznające i wybierze ten z najdłuższym dopasowaniem. (Jest to tak zwana zasada „maksymalnego chrupania”). Zwykle można to zoptymalizować, szczególnie jeśli wszystkie wzorce są wyrażeniami regularnymi. Na przykład (F) lex wykona tę optymalizację za Ciebie.
W twoim przypadku komplikacją jest to, że tokenizacja twojego języka jest zależna od kontekstu. W szczególności, gdy celem jest elem_or_data, jedynymi możliwymi tokenami są <,